using Microsoft.Extensions.Caching.Memory;
using SPI.AgentServer.Models;
using System.Security.Cryptography;
using System.Text;

namespace SPI.AgentServer.Services.Cache;

/// <summary>
/// 内存查询缓存服务实现
/// </summary>
public class InMemoryQueryCacheService : IQueryCacheService
{
    private readonly IMemoryCache _cache;
    private readonly ILogger<InMemoryQueryCacheService> _logger;
    private long _hitCount = 0;
    private long _missCount = 0;

    // 默认缓存过期时间
    private static readonly TimeSpan DefaultExpiration = TimeSpan.FromMinutes(30);

    public InMemoryQueryCacheService(
        IMemoryCache cache,
        ILogger<InMemoryQueryCacheService> logger)
    {
        _cache = cache;
        _logger = logger;
    }

    public Task<QueryResponse?> GetAsync(string query, string? databaseName = null)
    {
        var cacheKey = GenerateCacheKey(query, databaseName);
        
        if (_cache.TryGetValue(cacheKey, out QueryResponse? cachedResponse))
        {
            Interlocked.Increment(ref _hitCount);
            _logger.LogInformation("✅ 缓存命中：{Query}", TruncateQuery(query));
            
            // 标记为缓存结果（可以在前端显示）
            // 注意：这里直接返回缓存的响应
            
            return Task.FromResult(cachedResponse);
        }

        Interlocked.Increment(ref _missCount);
        _logger.LogInformation("❌ 缓存未命中：{Query}", TruncateQuery(query));
        
        return Task.FromResult<QueryResponse?>(null);
    }

    public Task SetAsync(string query, QueryResponse response, string? databaseName = null, TimeSpan? expiration = null)
    {
        var cacheKey = GenerateCacheKey(query, databaseName);
        var cacheExpiration = expiration ?? DefaultExpiration;

        var cacheOptions = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = cacheExpiration,
            SlidingExpiration = TimeSpan.FromMinutes(10), // 10分钟内无访问则过期
            Priority = CacheItemPriority.Normal
        };

        _cache.Set(cacheKey, response, cacheOptions);
        
        _logger.LogInformation("💾 已缓存查询结果：{Query}，过期时间：{Expiration}分钟", 
            TruncateQuery(query), 
            cacheExpiration.TotalMinutes);

        return Task.CompletedTask;
    }

    public Task RemoveAsync(string query, string? databaseName = null)
    {
        var cacheKey = GenerateCacheKey(query, databaseName);
        _cache.Remove(cacheKey);
        
        _logger.LogInformation("🗑️ 已清除缓存：{Query}", TruncateQuery(query));
        
        return Task.CompletedTask;
    }

    public Task ClearAllAsync()
    {
        // MemoryCache 不支持清除所有项，需要重新实现或使用其他方案
        // 这里记录日志
        _logger.LogWarning("⚠️ ClearAll 暂不支持，需要重启服务清除所有缓存");
        
        return Task.CompletedTask;
    }

    public Task<CacheStats> GetStatsAsync()
    {
        var stats = new CacheStats
        {
            HitCount = _hitCount,
            MissCount = _missCount,
            Count = 0 // MemoryCache 无法直接获取项数
        };

        return Task.FromResult(stats);
    }

    /// <summary>
    /// 生成缓存键（使用查询内容的哈希值）
    /// </summary>
    private string GenerateCacheKey(string query, string? databaseName)
    {
        // 标准化查询内容（去除空格、转小写）
        var normalizedQuery = query.Trim().ToLower().Replace(" ", "");
        var keyContent = $"{normalizedQuery}_{databaseName ?? "default"}";

        // 使用MD5生成固定长度的键
        using var md5 = MD5.Create();
        var hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(keyContent));
        var hashString = Convert.ToHexString(hashBytes);

        return $"query_cache_{hashString}";
    }

    /// <summary>
    /// 截断查询内容用于日志
    /// </summary>
    private string TruncateQuery(string query)
    {
        return query.Length > 50 ? query.Substring(0, 47) + "..." : query;
    }
}

